home *** CD-ROM | disk | FTP | other *** search
- /* kserver.c - task Keyboard Server interrupt driven */
-
- #include <synrtx.h>
- #include <ascii.h>
-
- #define BEEP 8
- #define NCHARS 80
- #define NOBODY 0
- #define EOI 0x20
-
- static word buffer[NCHARS], nCharsIn, charToSend, charToReceive;
- static task_t ksid, owner;
- static msg_t msg;
-
- /* handler numbers */
- #define ACQUIRE 0
- #define RELEASE 1
- #define HIT 2
- #define EXCEPTION 3
- #define GETCHAR 4
-
- #define PORT_A 0x60 /* 8255 */
- #define PORT_B 0x61
-
- static char kbdTab[] = {
- NUL,ESC,'1','2','3','4','5','6','7','8','9','0','-','=', /* 00-13 */
- BS,HT,'q','w','e','r','t','y','u','i','o','p','[',']',CR, /* 14-28 */
- 0,'a','s','d','f','g','h','j','k','l',';','\"','`', /* 29-41 */
- 0,'\\','z','x','c','v','b','n','m',',','.','/',0,'*', /* 34-55 */
- 0,' ',0 }; /* 56-58 */
-
- static byte code, status;
- static bool bufferFull;
-
- /* Hardware handler Keyboard for interrupt vector 9 */
- static handler Keyboard(void) {
- /* disable keyboard interrupt to not overwrite interrupt stack */
- dev_enable(DISABLE, 1, KEYBOARD);
- cpu_enable(); /* allow further interrupts */
-
- code = dev_byte(PORT_A);
- status = dev_byte(PORT_B);
- dev_setByte(status | 0x80, PORT_B); /* send ack _/^\_ to kbd */
- dev_setByte(status & 0x7F, PORT_B);
-
- if (code < 0x80 && kbdTab[code] && !bufferFull) {
- msg.value.w = (word)kbdTab[code];
- /* interrupt KeyboardServer.GetChar */
- task_interrupt(&msg);
- }
- /* keep all interrupts disable for the EOI and Exit */
- cpu_Disable();
- dev_setByte(EOI, 0x20);
- dev_enable(ENABLE, 1, KEYBOARD);
- }
-
- static handler Acquire(msg_t *msg_p) {
- register task_t caller = msg_p->srcTid;
- register task_t self = msg_p->dstTid;
-
- owner = caller;
- charToSend = charToReceive = nCharsIn = 0;
- bufferFull = FALSE;
-
- /* interrupt caller.Grant */
- msg_p->srcTid = self;
- msg_p->dstTid = caller;
- msg_p->dstHid = 0; /* GRANT = 0 */
- msg_p->type = msg_type_SYNC;
- task_interrupt(msg_p);
- }
-
- static handler Release(msg_t *msg_p) {
- register task_t caller = msg_p->srcTid;
- register task_t self = msg_p->dstTid;
-
- if (owner == caller) {
- owner = NOBODY;
- /* BufferFull is set to TRUE to avoid any software interrupts */
- bufferFull = TRUE;
- } else {
- /* interrupt self.Exception(caller) */
- msg_p->srcTid = msg_p->dstTid = self;
- msg_p->dstHid = EXCEPTION;
- msg_p->type = msg_type_WORD;
- msg_p->value.w = (word)caller;
- task_interrupt(msg_p);
- }
- }
-
- static handler Hit(msg_t *msg_p) {
- register task_t caller = msg_p->srcTid;
- register task_t self = msg_p->dstTid;
- register word c;
-
- if (owner == caller) {
- if (nCharsIn == 0) /* buffer empty ? */
- c = 0;
- else {
- c = buffer[charToSend] | 0x0100;
- charToSend = (charToSend + 1) % NCHARS;
- nCharsIn--;
- bufferFull = FALSE;
- }
-
- /* interrupt caller.GetChar(character) */
- msg_p->srcTid = msg_p->dstTid;
- msg_p->dstTid = caller;
- msg_p->dstHid = 1; /* GetChar = 1 */
- msg_p->type = msg_type_WORD;
- msg_p->value.w = c;
- task_interrupt(msg_p);
- } else {
- /* interrupt self.Exception(caller) */
- msg_p->srcTid = msg_p->dstTid = self;
- msg_p->dstHid = EXCEPTION;
- msg_p->type = msg_type_WORD;
- msg_p->value.w = (word)caller;
- task_interrupt(msg_p);
- }
- }
-
- static handler Exception(msg_t *msg_p) {
- io_putf("Illegal Access to KeyboardServer by Task #%w", msg_p->value.w);
- }
-
- static handler GetChar(msg_t *msg_p) {
- if (nCharsIn == NCHARS) /* buffer full ? */ {
- /* then, ignore the character (stops int from hard) */
- io_puts("\nKeyboardServer: buffer full !\n");
- bufferFull = TRUE;
- } else {
- buffer[charToReceive] = msg_p->value.w;
- charToReceive = (charToReceive + 1) % NCHARS;
- nCharsIn++;
- }
- }
-
- task KeyboardServer(void) {
- register word ps;
-
- ps = cpu_saveAndDisable();
- ksid = task_self();
-
- /* Install Keyboard hardware handler as the ISR for interrupt vector 9 */
- cpu_setHandler(INT9_KEYBOARD, Keyboard);
-
- /* Install software handlers */
- task_setHandler(5, Acquire, Release, Hit, Exception, GetChar);
-
- charToSend = charToReceive = nCharsIn = 0;
- /*
- * The KeyboardServer cannot receive characters while it is not yet
- * acquired, but should wait until a "client" gets it.
- * BufferFull is set to TRUE to avoid any software interrupts.
- */
- bufferFull = TRUE;
- msg.srcTid = msg.dstTid = ksid;
- msg.dstHid = GETCHAR;
- msg.type = msg_type_WORD;
- cpu_restore(ps);
- loop {
- /* enable wait Acquire */
- task_enableWait(NO_TIMEOUT, 1, ACQUIRE);
-
- do /* enable wait GetChar, Hit, Release, Exception */
- task_enableWait(NO_TIMEOUT,4,GETCHAR,HIT,RELEASE,EXCEPTION);
- while (owner != NOBODY);
- }
- }
-
-